#include "UrlFrontier.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include <queue>
#include <vector>

using namespace std;

UrlFrontier::UrlFrontier(const string& crFilePath,const int threadnum)
    :mUrlFilePath(crFilePath),iThreadNum(threadnum)
{
    urlFile.open(mUrlFilePath.c_str(),ios::app);
    ResumeOffset();
}

bool
UrlFrontier::AddUrl(const string& crUrlKey)
{
    urlFile<< crUrlKey <<endl;
    return true;
}

/// @todo 按照站点散列开，保证站点友好性
int
UrlFrontier::GetTaskQueue(vector<queue<Url> > & vQueue, Host& rHost)
{
    if (urlFile) {
        urlFile.flush();
    }
    SaveOffset();

    for (int i=0;i<iThreadNum;i++) {
        queue<Url> aQueue;
        vQueue.push_back(aQueue);
    }

    ifstream urlReadFile(mUrlFilePath.c_str());
    if (!urlReadFile) {
        return -1;
    }
    urlReadFile.seekg(curFileOffset);
    int count=0;
    string strurl;
    while(getline(urlReadFile,strurl) && count<DEFAULT_URL_CRAWLED) {
        Url aUrl;
        if(aUrl.ParseUrl(strurl)) {
            Host_Elem host_elem = rHost.GetElem(aUrl.mHost);
            aUrl.mIP = host_elem.IP;
            // added by liuyuan
            vQueue[(count++)%iThreadNum].push(aUrl);
        }
        //         cout<<aUrl.mOrginUrl<<endl;
        curFileOffset=(int)urlReadFile.tellg();
    }
    return count;
}

bool
UrlFrontier::ResumeOffset()
{
    mOffsetFilePath=mUrlFilePath+".pos";
    ifstream offsetFile(mOffsetFilePath.c_str(), ios::in);
    if(!offsetFile) {
        unsigned int pos=0;
        if(offsetFile>>pos){
            curFileOffset=pos;
            return true;
        }
    }
    curFileOffset=0;
    return false;
}

void UrlFrontier::SaveOffset()
{
    ofstream offsetFile(mOffsetFilePath.c_str(), ios::out|ios::trunc);

    offsetFile << curFileOffset << endl;
    offsetFile.close();
}
